﻿using System;
using System.API;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

using YTS.Logic.Log;

namespace RunQuartzConsole
{
    public class CommandExecutionHelp
    {
        private readonly ILog log;
        public CommandExecutionHelp(ILog log)
        {
            this.log = log;
        }

        /// <summary>
        /// 获取根据平台得到默认脚本路径
        /// </summary>
        public string GetOSPlatformScriptPath()
        {
            return "shell/" + (
                RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win.bat" :
                RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "linux.bat" :
                RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "OSX.bat" :
                RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD) ? "FreeBSD.bat" : "linux.bat"
                );
        }

        /// <summary>
        /// 执行指定的应用程序文件:
        /// (参考: .NET Core 跨平台执行命令、脚本 https://www.cnblogs.com/stulzq/p/9074965.html)
        /// </summary>
        /// <param name="appFileName"></param>
        public void Excute(string appFileName = null)
        {
            appFileName ??= GetOSPlatformScriptPath();

            var logArgs = new Dictionary<string, object>()
            {
                { "appFileName", appFileName }
            };
            log.Info("开始准备执行脚本文件", logArgs);
            try
            {
                //创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出
                var psi = new ProcessStartInfo(appFileName)
                {
                    RedirectStandardOutput = true
                };
                //启动
                var proc = Process.Start(psi);
                if (proc == null)
                {
                    log.Error("无法执行!", logArgs);
                    return;
                }
                StringBuilder stringBuilder = new StringBuilder();
                //开始读取
                using (var sr = proc.StandardOutput)
                {
                    while (!sr.EndOfStream)
                    {
                        stringBuilder.AppendLine(sr.ReadLine());
                    }
                    if (!proc.HasExited)
                    {
                        proc.Kill();
                    }
                }
                int ExitCode = proc.ExitCode;
                logArgs["ExitCode"] = ExitCode;
                log.Info("执行结束!", logArgs);
            }
            catch (Exception ex)
            {
                log.Error("执行指定文件出错!", ex, logArgs);
            }
        }

        [DllImport("shell32.dll")]
        public static extern int ShellExecute(IntPtr hwnd, StringBuilder lpszOp, StringBuilder lpszFile, StringBuilder lpszParams, StringBuilder lpszDir, int FsShowCmd);

        public void OpenDingDingHintAPP_ShellExecute()
        {
            var logArgs = new Dictionary<string, object>();
            log.Info("开始准备执行脚本文件", logArgs);
            string exeName = "DingDingHintAPP.exe";
            logArgs["exeName"] = exeName;
            string exePath = System.IO.Path.GetFullPath("../DingDingHintAPP/");
            logArgs["exePath"] = exePath;
            log.Info("执行准备完毕~", logArgs);
            int code = CommandExecutionHelp.ShellExecute(IntPtr.Zero, new StringBuilder("Open"), new StringBuilder(exeName), new StringBuilder(""), new StringBuilder(exePath), 1);
            logArgs["code"] = code;
            log.Info("执行结束!", logArgs);
        }
        public void OpenDingDingHintAPP_ProcessStart()
        {
            var logArgs = new Dictionary<string, object>();
            log.Info("开始准备执行脚本文件", logArgs);
            string exePath = System.IO.Path.GetFullPath("../DingDingHintAPP/DingDingHintAPP.exe");
            logArgs["exePath"] = exePath;
            log.Info("Process.Start 执行准备完毕~", logArgs);
            using (System.Diagnostics.Process.Start(exePath))
            {
                log.Info("using.内部执行!", logArgs);
            };
            log.Info("执行结束!", logArgs);
        }

        /// <summary>
        /// 使用大神写的调用引用程序代码
        /// </summary>
        public void OpenDingDingHintAPP_ApplicationLoader(string ExePath, string WindowLoginUserName)
        {
            var logArgs = new Dictionary<string, object>
            {
                ["ExePath"] = ExePath,
            };
            log.Info("ApplicationLoader.StartProcessAndBypassUAC.StartRun...", logArgs);
            bool result = ApplicationLoader.StartProcessAndBypassUAC(WindowLoginUserName, log, ExePath,
                out ApplicationLoader.PROCESS_INFORMATION procInfo);
            logArgs["procInfo"] = procInfo;
            logArgs["result"] = result;
            log.Info("ApplicationLoader.StartProcessAndBypassUAC.RunEnd!!!", logArgs);
        }
    }
}
